package model

import (
    adapter "git.inspur.com/x/iam-adapter-go"
    "git.inspur.com/x/iam-adapter-go/resource"
    "git.inspur.com/x/models"
    "strings"
)

type TriggerPage struct {
    TotalCount int64      `json:"totalCount" valid:"-"`
    PageNo     int        `json:"pageNo" valid:"-"`
    PageSize   int        `json:"pageSize" valid:"-"`
    Data       []*Trigger `json:"data" valid:"-"`
}

type Trigger struct {
    Id               string      `xorm:"pk" json:"id" valid:"-" `
    Creator          string      `json:"creator" valid:"-"`
    A5tId            string      `xorm:"account_id" json:"accountId" valid:"-"`
    CreatorName      string      `json:"creatorName" valid:"-"`
    A5tName          string      `xorm:"account_name" json:"accountName" valid:"-"`
    Name             string      `json:"name" valid:"-" `
    FuncId           string      `json:"funcId" valid:"-" `
    FuncName         string      `json:"funcName" valid:"-" `
    GroupName        string      `json:"groupName" valid:"-" `
    GroupDisplayName string      `json:"groupDisplayName" valid:"-" `
    GroupId          string      `json:"groupId" valid:"-" `
    Type             string      `json:"type" valid:"-" `
    Config           string      `json:"config" valid:"-" `
    Param            string      `json:"param" valid:"-" `
    IsEnable         int         `json:"isEnable" valid:"-" `
    TargetId         string      `json:"targetId" valid:"-" `
    TargetName       string      `json:"targetName" valid:"-" `
    TargetType       int         `json:"targetType" valid:"-" `
    RegionCode       string      `json:"regionCode" valid:"-" `
    RegionName       string      `json:"regionName" valid:"-" `
    CreateTime       models.Time `xorm:"created" json:"createTime" valid:"-" `
    UpdateTime       models.Time `xorm:"updated" json:"updateTime" valid:"-" `
    DeleteTime       models.Time `xorm:"deleted" json:"deleteTime" valid:"-" `
}

type ApigConfig struct {
    Id                      string   `json:"id" valid:"-"`
    Name                    string   `json:"name" valid:"-"`
    GroupId                 string   `json:"groupId" valid:"-" `
    AuthenticationMode      string   `json:"authenticationMode" valid:"-"`
    Style                   string   `json:"style" valid:"-" `
    Params                  []string `json:"params" valid:"-" `
    BackendTimeout          string   `json:"backendTimeout" valid:"-"`
    BackendType             string   `json:"backendType" valid:"-"`
    IsSupportedCors         string   `json:"isSupportedCors" valid:"-" `
    RequestMethod           string   `json:"requestMethod" valid:"-"`
    RequestProtocol         string   `json:"requestProtocol" valid:"-"`
    RequestPath             string   `json:"requestPath" valid:"-"`
    IsRelease               string   `json:"isRelease" valid:"-"`
    ReturnResultContentType string   `json:"returnResultContentType" valid:"-"`
    FaultTolerant           string   `json:"faultTolerant" valid:"-"`
    FcsGroupId              string   `json:"fcsGroupId" valid:"-"`
    FcsGroupName            string   `json:"fcsGroupName" valid:"-"`
    FcsFuncId               string   `json:"fcsFuncId" valid:"-"`
    FcsFuncName             string   `json:"fcsFuncName" valid:"-"`
    FcsVersionId            string   `json:"fcsVersionId" valid:"-"`
    FcsVersionName          string   `json:"fcsVersionName" valid:"-"`
    TestTriggerId           string   `json:"testTriggerId" valid:"-"`
    OnlineTriggerId         string   `json:"onlineTriggerId" valid:"-"`
    FcsTargetType           int      `json:"fcsTargetType" valid:"-"`
    FcsGroupDisplayName     string   `json:"fcsGroupDisplayName" valid:"-"`
}

type OssNotification struct {
    Id             string            `json:"id" valid:"-"`
    BucketName     string            `json:"bucketName" valid:"-"`
    Event          string            `json:"event" valid:"-" `
    KeyFilterRules map[string]string `json:"keyFilterRules" valid:"-"`
    Topic          string            `json:"topic" valid:"-" `
}

type HttpTriggerConfig struct {
    AuthType string `json:"authType" valid:"-"`
}

func CreateTrigger(trigger *Trigger) (*Trigger, error) {
    _, err := models.Engine.Table("fcs_trigger").InsertOne(trigger)
    if err != nil {
        _ = logger.Error("Insert trigger err : ", err)
        return nil, err
    }
    return trigger, nil
}

func DeleteTrigger(id string) error {
    if _, err := models.Engine.Table("fcs_trigger").ID(id).Delete(new(Trigger)); err != nil {
        _ = logger.Error("Delete trigger err : ", err)
        return err
    }
    return nil
}

func UpdateTrigger(trigger *Trigger) (*Trigger, error) {
    if _, err := models.Engine.Table("fcs_trigger").ID(trigger.Id).Cols("config").Cols("param").Cols("is_enable").
        Cols("target_id").Cols("target_name").Cols("target_type").Update(trigger); err != nil {
        _ = logger.Error("Update trigger err : ", err)
        return nil, err
    }
    return trigger, nil
}

func GetTriggerById(id string) (*Trigger, error) {
    t := &Trigger{}
    if _, err := models.Engine.Table("fcs_trigger").ID(id).Get(t); err != nil {
        _ = logger.Error("Get trigger By Id err : ", err)
        return nil, err
    }
    return t, nil
}

func GetTriggerByRuleId(ruleId string) (*Trigger, error) {
    t := &Trigger{}
    rIds := strings.Split(ruleId, ".")
    if _, err := models.Engine.Table("fcs_trigger").Where("group_name=?", rIds[0]).And("func_name=?", rIds[1]).And("name=?", rIds[2]).Get(t); err != nil {
        return nil, err
    }
    return t, nil
}

func GetTriggerList(gid, fid string, user *resource.User, name, tType string, pageNo, pageSize int) (*TriggerPage, error) {
    var ts []*Trigger
    session := models.Engine.Table("fcs_trigger").OrderBy("update_time desc")
    if name != "" {
        session = session.Where("INSTR(fcs_trigger.name,?)", name)
    }
    if err := session.Find(&ts, &Trigger{A5tId: user.AccountId, GroupId: gid, FuncId: fid, Type: tType}); err != nil {
        _ = logger.Error("Get triggerList err : ", err)
        return nil, err
    }

    filteredList := adapter.FilterListData(ts).([]interface{})
    resultList := make([]*Trigger, 0)
    for _, t := range filteredList {
        t, ok := t.(*Trigger)
        if ok {
            resultList = append(resultList, t)
        }
    }

    count := len(resultList)
    pageStart := (pageNo - 1) * pageSize
    pageEnd := pageNo * pageSize
    if pageStart > count-1 {
        pageStart = 0
        pageEnd = 0
    } else if pageEnd > count {
        pageEnd = count
    }

    tp := &TriggerPage{
        TotalCount: int64(count),
        PageNo:     pageNo,
        PageSize:   pageSize,
        Data:       resultList[pageStart:pageEnd],
    }

    return tp, nil
}

func CheckTriggerExist(uid, gid, fid, name string) (bool, error) {
    t := &Trigger{}
    return models.Engine.Table("fcs_trigger").Where("account_id=?", uid).And("group_id=?", gid).And("func_id=?", fid).And("name=?", name).Exist(t)
}

// 校验同一个函数的同一个版本/别名只能有一个 HTTP 触发器
func CheckHttpTriggerExist(triggerInfo *Trigger) (bool, error) {
    t := &Trigger{}
    return models.Engine.Table(
        "fcs_trigger").Where(
        "account_id=?", triggerInfo.A5tId).And(
        "group_id=?", triggerInfo.GroupId).And(
        "func_id=?", triggerInfo.FuncId).And(
        "type=?", "http").And(
        "target_name=?", triggerInfo.TargetName).Exist(t)
}

func CheckFunctionHasTrigger(user *resource.User, gid, fid string) (bool, error) {
    t := &Trigger{}
    return models.Engine.Table("fcs_trigger").
        Where("account_id=?", user.AccountId).
        And("group_id=?", gid).
        And("func_id=?", fid).
        Exist(t)
}

func GetUsingTargetTrigger(funcId, targetName string, targetType int) ([]*Trigger, error) {
    ts := make([]*Trigger, 0)
    if err := models.Engine.Table("fcs_trigger").Find(&ts, &Trigger{FuncId: funcId, TargetName: targetName, TargetType: targetType}); err != nil {
        _ = logger.Error("Get UsingTargetList err : ", err)
        return nil, err
    }
    return ts, nil
}
